package p.ithorns.tools.excel.read;

import cn.idev.excel.EasyExcel;
import org.apache.commons.collections4.MapUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.multipart.MultipartFile;
import p.ithorns.tools.excel.convert.Converters;
import p.ithorns.tools.excel.exception.ImportException;
import p.ithorns.tools.excel.model.ImportSheetResult;
import p.ithorns.tools.excel.model.RowError;

import java.io.InputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * SingleSheetImporter
 *
 * 单页导入
 *
 * @author HtL
 * @since 1.0.0
 * @date 2024/7/25 8:59
 */
public class SingleSheetImporter {

    private final static Logger log = LoggerFactory.getLogger(SingleSheetImporter.class);

    /**
     * 导入
     * <p>
     * 单(页)处理器
     *
     * @param file    -文件
     * @param handler -导入处理器
     * @return 导入结果
     */
    public static <T> ImportSheetResult<T> doImport(MultipartFile file, BaseImportHandler<T> handler) {
        // 1.校验参数
        if (Objects.isNull(file)) {
            throw new ImportException("MultipartFile对象为空, 上传处理失败");
        }

        // 2.进行导入  导入文件  解析、业务操作
        if (null == handler) {
            throw new ImportException("excel解析器为空, 上传处理失败");
        }

        log.info("导入Excel-Sheet: {}", handler.getSheetName());

        Map<String, Object> allCacheData = new HashMap<>(16);
        // 获取缓存参数
        handler.initCacheParamMap(allCacheData);
        try (InputStream inputStream = file.getInputStream()) {
            // 校验数据
            EasyExcel.read(inputStream)
                    .head(handler.getImportClass())
                    .sheet(handler.getSheetName())
                    .headRowNumber(handler.getHeadNumber())
                    .registerReadListener(handler)
                    .registerConverter(Converters.DATE_CONVERTER)
                    .registerConverter(Converters.DATE_TIME_CONVERTER)
                    .doRead();
        } catch (Exception e) {
            log.error("解析数据失败", e);
            // "解析校验数据失败, sheetName:" + importHandler.getSheetName()
            throw new ImportException(e.getMessage());
        }

        // 设置缓存参数 给后面流程使用
        Map<String, Object> curCacheData = handler.buildCacheParamMapForNext();
        if (MapUtils.isNotEmpty(curCacheData)) {
            allCacheData.putAll(curCacheData);
        }

        ImportSheetResult<T> sheetResult = new ImportSheetResult<>(handler.getImportClass());
        // 设置sheet页名称
        sheetResult.setSheetName(handler.getSheetName());
        // 设置成功数量
        sheetResult.setSuccessCount(handler.getSuccessNum());
        // 错误信息列表
        List<RowError<T>> rowErrors = handler.getRowErrors();
        if (null != rowErrors) {
            sheetResult.setRowErrors(rowErrors);
            sheetResult.setErrorCount(rowErrors.size());
        }

        return sheetResult;
    }

}